import * as THREE from 'three';
import M from 'scripts/main.js';
import { TWEEN } from 'three/addons/libs/tween.module.min.js';
import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
import {City} from 'scripts/city.js';
import {BuyBook} from 'scripts/buyBook.js';

class Shop {
	constructor(){	
		let animationID;
		const zis = '一男很会年学中如衣商吃也高飞坐楼英每由然主甚声李哥京周账空锅唱微猪酸胡园凉苹求咳江跑简客黑阴港规原修收绝奔挑领项宠眼适根寺挂玻帽拼婆贵抓洲乘扫删皇拿波欺陆邻策沿按郎农沉启杨吹辛屏侧攻赏腾横闲仪';

		let camera, scene, renderer, mouse, mesh,count=0;
		let controls,waveStart=false;
		let objects = [],targets = [];
		const m = new M();

		init();
		animate();

		function init() {
			THREE.Cache.enabled = true;
			camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1000, 10000 );
			camera.position.z = 6000;
			scene = new THREE.Scene();

			for ( let i = 0; i < zis.length; i ++ ) {
				let zi = zis.substr(i,1);
				let rare = Math.floor(Math.random()*32);
				let param = {id : i,zi:zi,rare :rare};
				const element = document.createElement( 'div' );
				element.className = 'element';
				element.tag=param;
				element.style.backgroundColor = 'rgba(0,127,127,' + m.getTransparency(rare) + ')';
				//这里是关键，不可以用click，估计是为了同时兼顾手机，
				//但奇怪的是不相应pointerup，所以在拖动控制时比较容易误触
				element.addEventListener('pointerdown', function() { 
					waveStart = false;
					dismiss(1000,this.tag.id);
					var param = this.tag;
					setTimeout(function(){
						destroy();
						new BuyBook(param);
					},1900);
				});

				const number = document.createElement( 'div' );
				number.className = 'number';
				number.textContent = m.getBookNo(i);
				element.appendChild( number );

				const symbol = document.createElement( 'div' );
				symbol.className = 'symbol';
				symbol.textContent = zi;
				element.appendChild( symbol );

				const details = document.createElement( 'div' );
				details.className = 'details';
				details.innerHTML = m.getRare(rare) + '<br>' + m.getPrice(rare);
				element.appendChild( details );

				const objectCSS = new CSS3DObject( element );
				objectCSS.position.x = Math.random() * 4000 - 2000;
				objectCSS.position.y = Math.random() * 4000 - 2000;
				objectCSS.position.z = Math.random() * 4000 - 2000;
				objectCSS.rotation.x = Math.random();
				objectCSS.rotation.y = Math.random();
				objectCSS.rotation.z = Math.random();
				objectCSS.position.up = true;
				scene.add( objectCSS );

				objects.push( objectCSS );

				const object = new THREE.Object3D();

				object.position.x = ( ( i % 4 ) * 500 ) - 800;
				object.position.y = ( - ( Math.floor( i / 4 ) % 4 ) * 400 ) + 600 + i;
				object.position.z = ( Math.floor( (zis.length-i-1) / 16 )-1 ) * 1000 - 100;
				object.rotation.x = 0;
				object.rotation.y = 0;
				object.rotation.z = 0;
				targets.push( object );
			}

			//

			renderer = new CSS3DRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.getElementById( 'container' ).appendChild( renderer.domElement );

			//

			controls = new TrackballControls( camera, renderer.domElement );
			controls.minDistance = 400;
			controls.maxDistance = 6000;
			controls.addEventListener( 'change', render );

			transform( 1000 );

			m.display("goback",true);
			m.getNode("goback").addEventListener('pointerdown', goback);
			window.addEventListener( 'resize', onWindowResize );
		}
		
		function goback(){
			destroy();
			new City();
		}
		
		function transform( duration ) {

			TWEEN.removeAll();

			for ( let i = 0; i < objects.length; i ++ ) {

				const object = objects[ i ];
				const target = targets[ i ];

				new TWEEN.Tween( object.position )
					.to( { x: target.position.x, y: target.position.y, z: target.position.z }, Math.random() * duration + duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

				new TWEEN.Tween( object.rotation )
					.to( { x: target.rotation.x, y: target.rotation.y, z: target.rotation.z }, Math.random() * duration + duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

			}

			new TWEEN.Tween( this )
				.to( {}, duration * 2 )
				.onUpdate( render )
				.onComplete(function(){
					waveStart = true;
				})
				.start();

		}

		function dismiss(duration,index) {
			TWEEN.removeAll();
			for ( let i = 0; i < objects.length; i ++ ) {

				const object = objects[ i ];
				if (index==i){
					new TWEEN.Tween( object.position )
						.to( { x: 0, y: 0, z: 6000 }, Math.random() * duration + duration )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();
					
				}else{
					new TWEEN.Tween( object.position )
						.to( { x:  Math.random() * 4000 - 2000, y:  Math.random() * 4000 - 2000, z:  Math.random() * 4000 - 2000 }, Math.random() * duration + duration )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();

					new TWEEN.Tween( object.rotation )
						.to( { x: Math.random(), y: Math.random(), z: Math.random() }, Math.random() * duration + duration )
						.easing( TWEEN.Easing.Exponential.InOut )
						.start();
				}
			}

			new TWEEN.Tween( this )
				.to( {}, duration * 2 )
				.onUpdate( render )
				.start();
		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

			render();

		}

		function animate() {

			animationID = requestAnimationFrame( animate );

			if (waveStart){
				for(let i=0;i<objects.length;i++){
					let y = ( - ( Math.floor( i / 4 ) % 4 ) * 400 ) + 600;
					if (objects[i].position.up ) {
						objects[i].position.y+=0.5;
						if (objects[i].position.y>y+16) objects[i].position.up=false;
					}else{
						objects[i].position.y-=0.5;
					  if (objects[i].position.y<y-16) objects[i].position.up=true;
					}
				}
				render();
			}else{
				TWEEN.update();
				
			}
			controls.update();

		}

		function render() {

			renderer.render( scene, camera );

		}

		function destroy(){
			cancelAnimationFrame(animationID)
			TWEEN.removeAll();
			scene.clear();
			controls.dispose (); 
			renderer.content = null;

			m.getNode("goback").removeEventListener('pointerdown', goback);
			window.removeEventListener( 'resize', onWindowResize );
			m.getNode("container").removeChild(renderer.domElement);
			scene = null;
			camera = null;
			controls = null;
			renderer = null;
			objects = null;
			targets = null;
		}			
	}
}
export { Shop };